package com.yan.club.sys.control;

import com.yan.club.result.Result;
import com.yan.club.sys.model.SysMenu;
import com.yan.club.sys.service.SysMenuService;
import com.yan.club.sys.vo.MenuVo;
import com.yan.club.sys.vo.RoleMenuTreeselectVo;
import com.yan.club.sys.vo.RouterVo;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

import static com.yan.club.auth.utils.SecurityUtil.getUser;
import static com.yan.club.auth.utils.SecurityUtil.getUserId;
import static com.yan.club.result.ResultCode.INTERNAL_SERVER_ERROR;

/**
 * @author 彦
 * @since 2024/1/25 16:35
 */
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController {

    @Resource
    private SysMenuService sysMenuService;

    /**
     * 动态构建路由
     *
     * @return
     */
    @GetMapping("/getRouters")
    public Result<List<RouterVo>> getRouters() {

        List<MenuVo> menuVos = sysMenuService.selectMenuTreeByUserId(getUserId());

        List<RouterVo> routerVos = sysMenuService.buildMenus(menuVos);

        return Result.success(routerVos);
    }

    /**
     * 获取菜单列表
     */
    @GetMapping("/list")
    @PreAuthorize("@check.hasAuthority('system:menu:list')")
    public Result<List<MenuVo>> list(SysMenu menu) {
        Long userId = getUserId();
        List<MenuVo> menus = sysMenuService.selectMenuList(menu, userId);

        return Result.success(menus);
    }

    /**
     * 修改菜单
     */
    @PreAuthorize("@check.hasAuthority('system:menu:edit')")
    @PutMapping
    public Result<String> update(@Validated @RequestBody SysMenu menu) {

        if (sysMenuService.checkMenuNameUnique(menu)) {
            return Result.error(INTERNAL_SERVER_ERROR.code,
                    "修改菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
        } else if (menu.getMenuId().equals(menu.getParentId())) {
            return Result.error(INTERNAL_SERVER_ERROR.code,
                    "修改菜单'" + menu.getMenuName() + "'失败，上级菜单不能选择自己");

        }
        menu.setUpdateBy(getUser().getUserName());
        menu.setUpdateTime(new Date());
        return sysMenuService.updateMenu(menu);
    }

    /**
     * 根据菜单Id查询
     */
    @PreAuthorize("@check.hasAuthority('system:menu:query')")
    @GetMapping("/{menuId}")
    public Result<SysMenu> getMenuByMenuId(@PathVariable Long menuId) {
        return sysMenuService.selectMenuById(menuId);
    }

    /**
     * 新增菜单
     */
    @PreAuthorize("@check.hasAuthority('system:menu:add')")
    @PostMapping("/save")
    public Result<String> save(@Validated @RequestBody SysMenu menu) {
        if (sysMenuService.checkMenuNameUnique(menu)) {
            return Result.error(INTERNAL_SERVER_ERROR.code,
                    "修改菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
        }
        menu.setUpdateBy(getUser().getUserName());
        menu.setUpdateTime(new Date());
        return sysMenuService.insertMenu(menu);
    }

    /**
     * 删除菜单
     */
    @PreAuthorize("@check.hasAuthority('system:menu:remove')")
    @DeleteMapping("/{menuId}")
    public Result<String> delete(@PathVariable("menuId") Long menuId) {
        if (sysMenuService.hasChildByMenuId(menuId)) {
            return Result.error(INTERNAL_SERVER_ERROR.code,
                    "存在子菜单,不允许删除");
        }
        if (sysMenuService.checkMenuExistRole(menuId)) {
            return Result.error(INTERNAL_SERVER_ERROR.code,
                    "菜单已分配,不允许删除");
        }
        return sysMenuService.deleteMenuById(menuId);
    }

    /**
     * 获取菜单下拉树列表
     */
    @GetMapping("/treeselect")
    public Result<List<MenuVo>> treeselect(SysMenu menu) {
        Long userId = getUserId();
        List<MenuVo> menus = sysMenuService.selectMenuList(menu, userId);
        List<MenuVo> treeSelects = sysMenuService.buildMenuTreeSelect(menus);
        return Result.success(treeSelects);
    }

    /**
     * 加载对应角色菜单列表树
     */
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public Result<RoleMenuTreeselectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
        Long userId = getUserId();
        List<MenuVo> menuVos = sysMenuService.selectMenuList(new SysMenu(), userId);
        List<MenuVo> menus = sysMenuService.buildMenuTreeSelect(menuVos);

        // 得到已经选择了的
        List<Long> checkedKeys = sysMenuService.selectMenuListByRoleId(roleId);

        RoleMenuTreeselectVo roleMenuTreeselectVo = new RoleMenuTreeselectVo();
        roleMenuTreeselectVo.setCheckedKeys(checkedKeys);
        roleMenuTreeselectVo.setMenus(menus);
        return Result.success(roleMenuTreeselectVo);
    }
}
